package com.nodecollege.cloud.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.nodecollege.cloud.common.constants.NCConstants;
import com.nodecollege.cloud.common.exception.UpmsException;
import com.nodecollege.cloud.common.model.BindVO;
import com.nodecollege.cloud.common.model.NCResult;
import com.nodecollege.cloud.common.model.QueryVO;
import com.nodecollege.cloud.common.model.po.*;
import com.nodecollege.cloud.common.model.vo.MenuTreeVO;
import com.nodecollege.cloud.common.utils.NCUtils;
import com.nodecollege.cloud.dao.mapper.*;
import com.nodecollege.cloud.service.OpRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author LC
 * @date 2020/2/18 21:27
 */
@Service
public class OpRoleServiceImpl implements OpRoleService {

    @Autowired
    private UpmsOpRoleMapper opRoleMapper;

    @Autowired
    private UpmsMenuMapper menuMapper;

    @Autowired
    private UpmsOpRoleMenuMapper opRoleMenuMapper;

    @Autowired
    private UpmsAdminMapper adminMapper;

    @Autowired
    private UpmsOpRoleAdminMapper opRoleAdminMapper;

    /**
     * 查询运营角色列表
     *
     * @param queryVO
     * @return
     */
    @Override
    public NCResult<UpmsOpRole> getOpRoleList(QueryVO<UpmsOpRole> queryVO) {
        List<UpmsOpRole> list = new ArrayList<>();
        Long total = 0L;
        if (NCConstants.INT_NEGATIVE_1.equals(queryVO.getPageSize())) {
            list = opRoleMapper.selectListByMap(queryVO.toMap());
            total = NCUtils.isNullOrEmpty(list) ? 0 : Long.parseLong(list.size() + "");
        } else {
            Page page = PageHelper.startPage(queryVO.getPageNum(), queryVO.getPageSize());
            if (queryVO.isSort()) {
                page.setOrderBy(queryVO.getSortKey() + " " + queryVO.getSortDirection());
            }
            list = opRoleMapper.selectListByMap(queryVO.toMap());
            total = page.getTotal();
        }
        return NCResult.ok(list, total);
    }

    /**
     * 添加运营角色
     *
     * @param opRole
     */
    @Override
    public void addOpRole(UpmsOpRole opRole) {
        NCUtils.nullOrEmptyThrow(opRole.getRoleName(), new UpmsException("", "角色名称不能为空！"));
        NCUtils.nullOrEmptyThrow(opRole.getNum(), new UpmsException("", "角色序号不能为空！"));

        QueryVO<UpmsOpRole> query = new QueryVO<>(new UpmsOpRole());
        query.getData().setRoleName(opRole.getRoleName());

        List<UpmsOpRole> exList = opRoleMapper.selectListByMap(query.toMap());
        NCUtils.notNullOrNotEmptyThrow(exList, new UpmsException("-1", "角色名称已使用！"));

        opRole.setCreateTime(new Date());
        opRole.setState(NCConstants.INT_1);
        opRoleMapper.insert(opRole);
    }

    /**
     * 修改运营角色
     *
     * @param opRole
     */
    @Override
    public void updateOpRole(UpmsOpRole opRole) {
        NCUtils.nullOrEmptyThrow(opRole.getOpRoleId(), new UpmsException("", "角色id不能为空！"));
        NCUtils.nullOrEmptyThrow(opRole.getRoleName(), new UpmsException("", "角色名称不能为空！"));
        NCUtils.nullOrEmptyThrow(opRole.getNum(), new UpmsException("", "角色序号不能为空！"));
        UpmsOpRole exRole = opRoleMapper.selectByPrimaryKey(opRole.getOpRoleId());
        NCUtils.nullOrEmptyThrow(exRole, new UpmsException("-1", "该角色不存在！"));

        QueryVO<UpmsOpRole> query = new QueryVO<>(new UpmsOpRole());
        query.getData().setRoleName(opRole.getRoleName());

        List<UpmsOpRole> exList = opRoleMapper.selectListByMap(query.toMap());
        if (exList.size() == 1 && !exList.get(0).getOpRoleId().equals(opRole.getOpRoleId())) {
            throw new UpmsException("-1", "角色名称已使用！");
        }
        opRole.setState(null);
        opRoleMapper.updateByPrimaryKeySelective(opRole);
    }

    /**
     * 删除运营角色
     *
     * @param opRole
     */
    @Override
    public void delOpRole(UpmsOpRole opRole) {
        NCUtils.nullOrEmptyThrow(opRole.getOpRoleId(), new UpmsException("", "角色id不能为空！"));
        UpmsOpRole exRole = opRoleMapper.selectByPrimaryKey(opRole.getOpRoleId());
        NCUtils.nullOrEmptyThrow(exRole, new UpmsException("-1", "该角色不存在！"));

        if (NCConstants.INT_0.equals(exRole.getState())) {
            throw new UpmsException("", "该角色不能解除！");
        }

        QueryVO<UpmsOpRole> query = new QueryVO<>(new UpmsOpRole());
        query.getData().setOpRoleId(exRole.getOpRoleId());
        List<UpmsAdmin> adminList = adminMapper.selectListByOpRoleAdmin(query.toMap());
        NCUtils.notNullOrNotEmptyThrow(adminList, new UpmsException("", "该角色存在绑定管理员，不能删除"));


        List<UpmsMenu> menuList = menuMapper.selectListByOpRoleMenu(query.toMap());
        NCUtils.notNullOrNotEmptyThrow(menuList, new UpmsException("", "该角色存在绑定菜单，不能删除"));

        opRoleMapper.deleteByPrimaryKey(opRole.getOpRoleId());
    }

    /**
     * 查询所有运营菜单树
     *
     * @return
     */
    @Override
    public List<MenuTreeVO> getOpMenuTree() {
        QueryVO<UpmsApp> queryVO = new QueryVO<>(new UpmsApp());
        queryVO.getData().setAppType(NCConstants.INT_0);
        return MenuTreeVO.getMenuTree(menuMapper.selectListByApp(queryVO.toMap()));
    }

    /**
     * 根据运营角色查询运营菜单
     *
     * @param opRole
     * @return
     */
    @Override
    public List<UpmsMenu> getOpRoleMenuList(UpmsOpRole opRole) {
        NCUtils.nullOrEmptyThrow(opRole.getOpRoleId(), new UpmsException("", "运营角色id不能为空！"));
        return menuMapper.selectListByOpRoleMenu(new QueryVO<>(opRole).toMap());
    }

    /**
     * 绑定解绑运营角色菜单信息
     *
     * @param bindVO
     */
    @Override
    public void bindOpRoleMenu(BindVO bindVO) {
        NCUtils.nullOrEmptyThrow(bindVO.getMainSource(), new UpmsException("-1", "参数错误！"));

        // 已绑定的数据
        UpmsOpRoleMenu query = new UpmsOpRoleMenu();
        // 最终保留的数据
        List<UpmsOpRoleMenu> endList = new ArrayList<>();
        if (bindVO.getMainSource()) {
            NCUtils.nullOrEmptyThrow(bindVO.getSourceIds(), new UpmsException("-1", "绑定入参有误"));
            query.setOpRoleId(bindVO.getSourceIds().get(0));
            bindVO.getSourceIds().forEach(opRoleId -> {
                bindVO.getTargetIds().forEach(menuId -> {
                    UpmsOpRoleMenu end = new UpmsOpRoleMenu();
                    end.setMenuId(menuId);
                    end.setOpRoleId(opRoleId);
                    end.setState(NCConstants.INT_1);
                    endList.add(end);
                });
            });
        } else {
            NCUtils.nullOrEmptyThrow(bindVO.getTargetIds(), new UpmsException("-1", "绑定入参有误！"));
            query.setMenuId(bindVO.getTargetIds().get(0));
            bindVO.getTargetIds().forEach(menuId -> {
                bindVO.getSourceIds().forEach(opRoleId -> {
                    UpmsOpRoleMenu end = new UpmsOpRoleMenu();
                    end.setMenuId(menuId);
                    end.setOpRoleId(opRoleId);
                    end.setState(NCConstants.INT_1);
                    endList.add(end);
                });
            });
        }
        List<UpmsOpRoleMenu> exList = opRoleMenuMapper.selectListByOpRoleMenu(query);

        // 取消绑定的数据
        exList.forEach(ex -> {
            Boolean delFlag = true;
            for (int i = 0; i < endList.size(); i++) {
                if (ex.getMenuId().equals(endList.get(i).getMenuId())
                        && ex.getOpRoleId().equals(endList.get(i).getOpRoleId())) {
                    delFlag = false;
                    break;
                }
            }
            if (delFlag) {
                if (NCConstants.INT_0.equals(ex.getState())) {
                    throw new UpmsException("", "该关系不能解除！");
                }
                opRoleMenuMapper.deleteByPrimaryKey(ex.getOpRoleMenuId());
            }
        });

        // 新增绑定的数据
        endList.forEach(end -> {
            Boolean addFlag = true;
            for (int i = 0; i < exList.size(); i++) {
                if (end.getMenuId().equals(exList.get(i).getMenuId())
                        && end.getOpRoleId().equals(exList.get(i).getOpRoleId())) {
                    addFlag = false;
                    break;
                }
            }
            if (addFlag) {
                opRoleMenuMapper.insert(end);
            }
        });
    }

    /**
     * 根据角色信息查询绑定的管理员信息
     *
     * @param queryVO
     * @return
     */
    @Override
    public NCResult<UpmsAdmin> getAdminListByOpRole(QueryVO<UpmsOpRoleAdmin> queryVO) {
        NCUtils.nullOrEmptyThrow(queryVO.getData().getOpRoleId(), new UpmsException("", "运营角色id不能为空！"));
        List<UpmsAdmin> list = new ArrayList<>();
        Long total = 0L;
        if (NCConstants.INT_NEGATIVE_1.equals(queryVO.getPageSize())) {
            list = adminMapper.selectListByOpRoleAdmin(queryVO.toMap());
            total = NCUtils.isNullOrEmpty(list) ? 0 : Long.parseLong(list.size() + "");
        } else {
            Page page = PageHelper.startPage(queryVO.getPageNum(), queryVO.getPageSize());
            if (queryVO.isSort()) {
                page.setOrderBy(queryVO.getSortKey() + " " + queryVO.getSortDirection());
            }
            list = adminMapper.selectListByOpRoleAdmin(queryVO.toMap());
            total = page.getTotal();
        }
        return NCResult.ok(list, total);
    }

    /**
     * 绑定角色管理员关系
     *
     * @param bindVO
     */
    @Override
    public NCResult bindOpRoleAdmin(BindVO bindVO) {
        NCUtils.nullOrEmptyThrow(bindVO.getMainSource(), new UpmsException("-1", "参数错误！"));

        // 最终保留的数据
        List<UpmsOpRoleAdmin> endList = new ArrayList<>();
        UpmsOpRoleAdmin query = new UpmsOpRoleAdmin();
        if (bindVO.getMainSource()) {
            NCUtils.nullOrEmptyThrow(bindVO.getSourceIds(), new UpmsException("", "绑定入参有误!"));
            query.setOpRoleId(bindVO.getSourceIds().get(0));
            bindVO.getSourceIds().forEach(opRoleId -> {
                bindVO.getTargetIds().forEach(adminId -> {
                    UpmsOpRoleAdmin end = new UpmsOpRoleAdmin();
                    end.setOpRoleId(opRoleId);
                    end.setAdminId(adminId);
                    end.setState(NCConstants.INT_1);
                    endList.add(end);
                });
            });
        } else {
            NCUtils.nullOrEmptyThrow(bindVO.getTargetIds(), new UpmsException("", "绑定入参有误!"));
            query.setAdminId(bindVO.getTargetIds().get(0));
            bindVO.getTargetIds().forEach(adminId -> {
                bindVO.getSourceIds().forEach(opRoleId -> {
                    UpmsOpRoleAdmin end = new UpmsOpRoleAdmin();
                    end.setOpRoleId(opRoleId);
                    end.setAdminId(adminId);
                    end.setState(NCConstants.INT_1);
                    endList.add(end);
                });
            });
        }

        // 已绑定的数据
        List<UpmsOpRoleAdmin> exList = opRoleAdminMapper.selectListByOpRoleAdmin(query);

        AtomicInteger newBindSize = new AtomicInteger();
        AtomicInteger oldBindSize = new AtomicInteger();
        // 新增绑定的数据
        endList.forEach(end -> {
            Boolean addFlag = true;
            for (int i = 0; i < exList.size(); i++) {
                if (end.getOpRoleId().equals(exList.get(i).getOpRoleId())
                        && end.getAdminId().equals(exList.get(i).getAdminId())) {
                    addFlag = false;
                    break;
                }
            }
            if (addFlag) {
                opRoleAdminMapper.insert(end);
                newBindSize.getAndIncrement();
            } else {
                oldBindSize.getAndIncrement();
            }
        });
        String message = "新增绑定 " + newBindSize.toString() + "条";
        if (oldBindSize.toString().compareTo("0") > 0) {
            message = message + ", 历史已绑定 " + oldBindSize.toString() + "条";
        }
        return NCResult.ok(message);
    }

    /**
     * 解除绑定关系
     *
     * @param opRoleAdmin
     */
    @Override
    public void unBindOpRoleAdmin(UpmsOpRoleAdmin opRoleAdmin) {
        NCUtils.nullOrEmptyThrow(opRoleAdmin.getOpRoleId(), new UpmsException("", "角色id不能为空！"));
        NCUtils.nullOrEmptyThrow(opRoleAdmin.getAdminId(), new UpmsException("", "成员id不能为空！"));
        List<UpmsOpRoleAdmin> exList = opRoleAdminMapper.selectListByOpRoleAdmin(opRoleAdmin);
        NCUtils.nullOrEmptyThrow(exList, new UpmsException("", "绑定关系不存在！"));
        if (exList.get(0).getState() == NCConstants.INT_0) {
            throw new UpmsException("", "该绑定关系不能解除！");
        }
        opRoleAdminMapper.deleteByPrimaryKey(exList.get(0).getOpRoleAdminId());
    }
}
